/*-----------------------------------------------------------------------------
 * detail/platform.h
 *
 * Currently supported platform indentification defines include:
 */
/*
 *    PLATFORM_ANDROID
 *    PLATFORM_APPLE
 *    PLATFORM_IPHONE
 *    PLATFORM_IPHONE_SIMULATOR
 *    PLATFORM_OSX
 *    PLATFORM_LINUX
 *    PLATFORM_SAMSUNG_TV
 *    PLATFORM_WINDOWS
 *    PLATFORM_WIN32
 *    PLATFORM_WIN64
 *    PLATFORM_WINDOWS_PHONE
 *    PLATFORM_WINRT
 *    PLATFORM_SUN
 *    PLATFORM_LRB (Larrabee)
 *    PLATFORM_POSIX     (pseudo-platform; may be defined along with another platform like PLATFORM_LINUX, PLATFORM_UNIX, PLATFORM_QNX)
 *    PLATFORM_UNIX      (pseudo-platform; may be defined along with another platform like PLATFORM_LINUX)
 *    PLATFORM_CYGWIN    (pseudo-platform; may be defined along with another platform like PLATFORM_LINUX)
 *    PLATFORM_MINGW     (pseudo-platform; may be defined along with another platform like PLATFORM_WINDOWS)
 *    PLATFORM_MICROSOFT (pseudo-platform; may be defined along with another platform like PLATFORM_WINDOWS)
 *
 *    ABI_ARM_LINUX      (a.k.a. "eabi". for all platforms that use the CodeSourcery GNU/Linux toolchain, like Android)
 *    ABI_ARM_APPLE      (similar to eabi but not identical)
 *    ABI_ARM64_APPLE    (similar to eabi but not identical) https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
 *    ABI_ARM_WINCE      (similar to eabi but not identical)
 *
 * Other definitions emanated from this file inclue:
 *    PLATFORM_NAME = <string>
 *    PLATFORM_DESCRIPTION = <string>
 *    PROCESSOR_XXX
 *    MISALIGNED_SUPPORT_LEVEL=0|1|2
 *    SYSTEM_LITTLE_ENDIAN | SYSTEM_BIG_ENDIAN
 *    ASM_STYLE_ATT | ASM_STYLE_INTEL | ASM_STYLE_MOTOROLA
 *    PLATFORM_PTR_SIZE = <integer size in bytes>
 *    PLATFORM_WORD_SIZE = <integer size in bytes>
 *    CACHE_LINE_SIZE = <integer size in bytes>
 *---------------------------------------------------------------------------*/

/*
	PLATFORM_MOBILE
	PLATFORM_MOBILE is a peer to PLATORM_DESKTOP and PLATFORM_CONSOLE. Their definition is qualitative rather
	than quantitative, and refers to the general (usually weaker) capabilities of the machine. Mobile devices have a
	similar set of weaknesses that are useful to generally categorize. The primary motivation is to avoid code that
	tests for multiple mobile platforms on a line and needs to be updated every time we get a new one.
	For example, mobile platforms tend to have weaker ARM processors, don't have full multiple processor support,
	are hand-held, don't have mice (though may have touch screens or basic cursor controls), have writable solid
	state permanent storage. Production user code shouldn't have too many expecations about the meaning of this define.

	PLATFORM_DESKTOP
	This is similar to PLATFORM_MOBILE in its qualitative nature and refers to platforms that are powerful.
	For example, they nearly always have virtual memory, mapped memory, hundreds of GB of writable disk sto rage,
	TCP/IP network connections, mice, keyboards, 512+ MB of RAM, multiprocessing, multiple display support.
	Production user code shouldn't have too many expecations about the meaning of this define.

	PLATFORM_CONSOLE
	This is similar to PLATFORM_MOBILE in its qualitative nature and refers to platforms that are consoles.
	This means platforms that are connected to TVs, are fairly powerful (especially graphics-wise), are tightly
	controlled by vendors, tend not to have mapped memory, tend to have TCP/IP, don't have multiple process support
	though they might have multiple CPUs, support TV output only. Production user code shouldn't have too many
	expecations about the meaning of this define.

*/


#ifndef CONFIG_DETAIL_PLATFORM_H_
#define CONFIG_DETAIL_PLATFORM_H_


// Cygwin
// This is a pseudo-platform which will be defined along with PLATFORM_LINUX when
// using the Cygwin build environment.
#if defined(__CYGWIN__)
	#define PLATFORM_CYGWIN 1
	#define PLATFORM_DESKTOP 1
#endif

// MinGW
// This is a pseudo-platform which will be defined along with PLATFORM_WINDOWS when
// using the MinGW Windows build environment.
#if defined(__MINGW32__) || defined(__MINGW64__)
	#define PLATFORM_MINGW 1
	#define PLATFORM_DESKTOP 1
#endif

#if   defined(PLATFORM_LRB) || defined(__LRB__) || (defined(__EDG__) && defined(__ICC) && defined(__x86_64__))
	#undef  PLATFORM_LRB
	#define PLATFORM_LRB         1
	#define PLATFORM_NAME        "Larrabee"
	#define PLATFORM_DESCRIPTION "Larrabee on LRB1"
	#define PROCESSOR_X86_64 1
	#if defined(BYTE_ORDER) && (BYTE_ORDER == 4321)
		#define SYSTEM_BIG_ENDIAN 1
	#else
		#define SYSTEM_LITTLE_ENDIAN 1
	#endif
	#define PROCESSOR_LRB 1
	#define PROCESSOR_LRB1 1       // Larrabee version 1
	#define ASM_STYLE_ATT 1        // Both types of asm style
	#define ASM_STYLE_INTEL 1      // are supported.
	#define PLATFORM_DESKTOP 1

// Android (Google phone OS)
#elif defined(PLATFORM_ANDROID) || defined(__ANDROID__)
	#undef  PLATFORM_ANDROID
	#define PLATFORM_ANDROID 1
	#define PLATFORM_LINUX 1
	#define PLATFORM_UNIX 1
	#define PLATFORM_POSIX 1
	#define PLATFORM_NAME "Android"
	#define ASM_STYLE_ATT 1
	#if defined(__arm__)
		#define ABI_ARM_LINUX 1  // a.k.a. "ARM eabi"
		#define PROCESSOR_ARM32 1
		#define PLATFORM_DESCRIPTION "Android on ARM"
	#elif defined(__i386__)
		#define PROCESSOR_X86 1
		#define PLATFORM_DESCRIPTION "Android on x86"
	#else
		#error Unknown processor
	#endif
	#if !defined(SYSTEM_BIG_ENDIAN) && !defined(SYSTEM_LITTLE_ENDIAN)
		#define SYSTEM_LITTLE_ENDIAN 1
	#endif
	#define PLATFORM_MOBILE 1

// Samsung SMART TV - a Linux-based smart TV
#elif defined(PLATFORM_SAMSUNG_TV)
	#undef  PLATFORM_SAMSUNG_TV
	#define PLATFORM_SAMSUNG_TV 1
	#define PLATFORM_LINUX 1
	#define PLATFORM_UNIX 1
	#define PLATFORM_POSIX 1
	#define PLATFORM_NAME "SamsungTV"
	#define PLATFORM_DESCRIPTION "Samsung SMART TV on ARM"
	#define ASM_STYLE_ATT 1
	#define SYSTEM_LITTLE_ENDIAN 1
	#define PROCESSOR_ARM32 1
	#define ABI_ARM_LINUX 1 // a.k.a. "ARM eabi"
	#define PROCESSOR_ARM7 1

#elif defined(__APPLE__) && __APPLE__
	#include <TargetConditionals.h>

	// Apple family of operating systems.
	#define PLATFORM_APPLE
	#define PLATFORM_POSIX 1

	// iPhone
	// TARGET_OS_IPHONE will be undefined on an unknown compiler, and will be defined on gcc.
	#if defined(PLATFORM_IPHONE) || defined(__IPHONE__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)
		#undef  PLATFORM_IPHONE
		#define PLATFORM_IPHONE 1
		#define PLATFORM_NAME "iPhone"
		#define ASM_STYLE_ATT 1
		#define POSIX_THREADS_AVAILABLE 1
		#if defined(__arm__)
			#define ABI_ARM_APPLE 1
			#define PROCESSOR_ARM32 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "iPhone on ARM"
		#elif defined(__aarch64__) || defined(__AARCH64)
			#define ABI_ARM64_APPLE 1
			#define PROCESSOR_ARM64 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "iPhone on ARM64"
		#elif defined(__i386__)
			#define PLATFORM_IPHONE_SIMULATOR 1
			#define PROCESSOR_X86 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "iPhone simulator on x86"
		#elif defined(__x86_64) || defined(__amd64)
			#define PROCESSOR_X86_64 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "iPhone simulator on x64"
		#else
			#error Unknown processor
		#endif
		#define PLATFORM_MOBILE 1

	// Macintosh OSX
	// TARGET_OS_MAC is defined by the Metrowerks and older AppleC compilers.
	// Howerver, TARGET_OS_MAC is defined to be 1 in all cases.
	// __i386__ and __intel__ are defined by the GCC compiler.
	// __dest_os is defined by the Metrowerks compiler.
	// __MACH__ is defined by the Metrowerks and GCC compilers.
	// powerc and __powerc are defined by the Metrowerks and GCC compilers.
	#elif defined(PLATFORM_OSX) || defined(__MACH__) || (defined(__MSL__) && (__dest_os == __mac_os_x))
		#undef  PLATFORM_OSX
		#define PLATFORM_OSX 1
		#define PLATFORM_UNIX 1
		#define PLATFORM_POSIX 1
	  //#define PLATFORM_BSD 1           We don't currently define this. OSX has some BSD history but a lot of the API is different.
		#define PLATFORM_NAME "OSX"
		#if defined(__i386__) || defined(__intel__)
			#define PROCESSOR_X86 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on x86"
		#elif defined(__x86_64) || defined(__amd64)
			#define PROCESSOR_X86_64 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on x64"
		#elif defined(__arm__)
			#define ABI_ARM_APPLE 1
			#define PROCESSOR_ARM32 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on ARM"
		#elif defined(__aarch64__) || defined(__AARCH64)
			#define ABI_ARM64_APPLE 1
			#define PROCESSOR_ARM64 1
			#define SYSTEM_LITTLE_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on ARM64"
		#elif defined(__POWERPC64__) || defined(__powerpc64__)
			#define PROCESSOR_POWERPC 1
			#define CS_UNDEFINED_STRING 1
			#define SYSTEM_BIG_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on PowerPC 64"
		#elif defined(__POWERPC__) || defined(__powerpc__)
			#define PROCESSOR_POWERPC 1
			#define PROCESSOR_POWERPC_32 1
			#define SYSTEM_BIG_ENDIAN 1
			#define PLATFORM_DESCRIPTION "OSX on PowerPC"
		#else
			#error Unknown processor
		#endif
		#if defined(__GNUC__)
			#define ASM_STYLE_ATT 1
		#else
			#define ASM_STYLE_MOTOROLA 1
		#endif
		#define PLATFORM_DESKTOP 1
	#else
		#error Unknown Apple Platform
	#endif

// Linux
// __linux and __linux__ are defined by the GCC and Borland compiler.
// __i386__ and __intel__ are defined by the GCC compiler.
// __i386__ is defined by the Metrowerks compiler.
// _M_IX86 is defined by the Borland compiler.
// __sparc__ is defined by the GCC compiler.
// __powerpc__ is defined by the GCC compiler.
#elif defined(PLATFORM_LINUX) || (defined(__linux) || defined(__linux__))
	#undef  PLATFORM_LINUX
	#define PLATFORM_LINUX 1
	#define PLATFORM_UNIX 1
	#define PLATFORM_POSIX 1
	#define PLATFORM_NAME "Linux"
	#if defined(__i386__) || defined(__intel__) || defined(_M_IX86)
		#define PROCESSOR_X86 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Linux on x86"
	#elif defined(__x86_64__)
		#define PROCESSOR_X86_64 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Linux on x64"
	#elif defined(__powerpc64__)
		#define PROCESSOR_POWERPC 1
		#define CS_UNDEFINED_STRING 1
		#define SYSTEM_BIG_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Linux on PowerPC 64"
	#elif defined(__powerpc__)
		#define PROCESSOR_POWERPC 1
		#define PROCESSOR_POWERPC_32 1
		#define SYSTEM_BIG_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Linux on PowerPC"
	#else
		#error Unknown processor
		#error Unknown endianness
	#endif
	#if defined(__GNUC__)
		#define ASM_STYLE_ATT 1
	#endif
	#define PLATFORM_DESKTOP 1


#elif defined(PLATFORM_BSD) || (defined(__BSD__) || defined(__FreeBSD__))
	#undef  PLATFORM_BSD
	#define PLATFORM_BSD 1
	#define PLATFORM_UNIX 1
	#define PLATFORM_POSIX 1     // BSD's posix complaince is not identical to Linux's
	#define PLATFORM_NAME "BSD Unix"
	#if defined(__i386__) || defined(__intel__)
		#define PROCESSOR_X86 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "BSD on x86"
	#elif defined(__x86_64__)
		#define PROCESSOR_X86_64 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "BSD on x64"
	#elif defined(__powerpc64__)
		#define PROCESSOR_POWERPC 1
		#define CS_UNDEFINED_STRING 1
		#define SYSTEM_BIG_ENDIAN 1
		#define PLATFORM_DESCRIPTION "BSD on PowerPC 64"
	#elif defined(__powerpc__)
		#define PROCESSOR_POWERPC 1
		#define PROCESSOR_POWERPC_32 1
		#define SYSTEM_BIG_ENDIAN 1
		#define PLATFORM_DESCRIPTION "BSD on PowerPC"
	#else
		#error Unknown processor
		#error Unknown endianness
	#endif
	#if !defined(PLATFORM_FREEBSD) && defined(__FreeBSD__)
		#define PLATFORM_FREEBSD 1 // This is a variation of BSD.
	#endif
	#if defined(__GNUC__)
		#define ASM_STYLE_ATT 1
	#endif
	#define PLATFORM_DESKTOP 1


#elif defined(PLATFORM_WINDOWS_PHONE)
	#undef PLATFORM_WINDOWS_PHONE
	#define PLATFORM_WINDOWS_PHONE 1
	#define PLATFORM_NAME "Windows Phone"
	#if defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__)
		#define PROCESSOR_X86_64 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows Phone on x64"
	#elif defined(_M_IX86) || defined(_X86_)
		#define PROCESSOR_X86 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows Phone on X86"
	#elif defined(_M_ARM)
		#define ABI_ARM_WINCE 1
		#define PROCESSOR_ARM32 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows Phone on ARM"
	#else //Possibly other Windows Phone variants
		#error Unknown processor
		#error Unknown endianness
	#endif
	#define PLATFORM_MICROSOFT 1

	// WINAPI_FAMILY defines - mirrored from winapifamily.h
	#define WINAPI_FAMILY_APP         1
	#define WINAPI_FAMILY_DESKTOP_APP 2
	#define WINAPI_FAMILY_PHONE_APP   3

	#if defined(WINAPI_FAMILY)
		#include <winapifamily.h>
		#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
			#define WINAPI_FAMILY WINAPI_FAMILY_PHONE_APP
		#else
			#error Unsupported WINAPI_FAMILY for Windows Phone
		#endif
	#else
		#error WINAPI_FAMILY should always be defined on Windows Phone.
	#endif

	// Macro to determine if a partition is enabled.
	#define WINAPI_FAMILY_PARTITION(Partition)   (Partition)

	// Enable the appropriate partitions for the current family
	#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
	#   define WINAPI_PARTITION_CORE    1
	#   define WINAPI_PARTITION_PHONE   1
	#   define WINAPI_PARTITION_APP     1
	#else
	#   error Unsupported WINAPI_FAMILY for Windows Phone
	#endif


// Windows
// _WIN32 is defined by the VC++, Intel and GCC compilers.
// _WIN64 is defined by the VC++, Intel and GCC compilers.
// __WIN32__ is defined by the Borland compiler.
// __INTEL__ is defined by the Metrowerks compiler.
// _M_IX86, _M_AMD64 and _M_IA64 are defined by the VC++, Intel, and Borland compilers.
// _X86_, _AMD64_, and _IA64_ are defined by the Metrowerks compiler.
// _M_ARM is defined by the VC++ compiler.
#elif (defined(PLATFORM_WINDOWS) || (defined(_WIN32) || defined(__WIN32__) || defined(_WIN64))) && !defined(CS_UNDEFINED_STRING)
	#undef  PLATFORM_WINDOWS
	#define PLATFORM_WINDOWS 1
	#define PLATFORM_NAME "Windows"
	#ifdef _WIN64 // VC++ defines both _WIN32 and _WIN64 when compiling for Win64.
		#define PLATFORM_WIN64 1
	#else
		#define PLATFORM_WIN32 1
	#endif
	#if defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__)
		#define PROCESSOR_X86_64 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows on x64"
	#elif defined(_M_IX86) || defined(_X86_)
		#define PROCESSOR_X86 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows on X86"
	#elif defined(_M_IA64) || defined(_IA64_)
		#define PROCESSOR_IA64 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows on IA-64"
	#elif defined(_M_ARM)
		#define ABI_ARM_WINCE 1
		#define PROCESSOR_ARM32 1
		#define SYSTEM_LITTLE_ENDIAN 1
		#define PLATFORM_DESCRIPTION "Windows on ARM"
	#else //Possibly other Windows CE variants
		#error Unknown processor
		#error Unknown endianness
	#endif
	#if defined(__GNUC__)
		#define ASM_STYLE_ATT 1
	#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__ICL)
		#define ASM_STYLE_INTEL 1
	#endif
	#define PLATFORM_DESKTOP 1
	#define PLATFORM_MICROSOFT 1

	// WINAPI_FAMILY defines to support Windows 8 Metro Apps - mirroring winapifamily.h in the Windows 8 SDK
	#define WINAPI_PARTITION_DESKTOP   0x00000001
	#define WINAPI_PARTITION_APP       0x00000002
	#define WINAPI_FAMILY_APP          WINAPI_PARTITION_APP
	#define WINAPI_FAMILY_DESKTOP_APP  (WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_APP)

	#if defined(WINAPI_FAMILY)
		#if defined(_MSC_VER)
			#pragma warning(push, 0)
		#endif
		#include <winapifamily.h>
		#if defined(_MSC_VER)
			#pragma warning(pop)
		#endif
		#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
			#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
		#elif WINAPI_FAMILY == WINAPI_FAMILY_APP
			#define WINAPI_FAMILY WINAPI_FAMILY_APP
		#else
			#error Unsupported WINAPI_FAMILY
		#endif
	#else
		#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
	#endif

	#define WINAPI_FAMILY_PARTITION(Partition)   ((WINAPI_FAMILY & Partition) == Partition)

	// PLATFORM_WINRT
	// This is a subset of Windows which is used for tablets and the "Metro" (restricted) Windows user interface.
	// WinRT doesn't doesn't have access to the Windows "desktop" API, but WinRT can nevertheless run on 
	// desktop computers in addition to tablets. The Windows Phone API is a subset of WinRT and is not included
	// in it due to it being only a part of the API.
	#if (defined(PLATFORM_WINDOWS) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
		#define PLATFORM_WINRT 1 
	#endif

// Sun (Solaris)
// __SUNPRO_CC is defined by the Sun compiler.
// __sun is defined by the GCC compiler.
// __i386 is defined by the Sun and GCC compilers.
// __sparc is defined by the Sun and GCC compilers.
#else
	#error Unknown platform
	#error Unknown processor
	#error Unknown endianness
#endif

#ifndef PROCESSOR_ARM
	#if defined(PROCESSOR_ARM32) || defined(PROCESSOR_ARM64) || defined(PROCESSOR_ARM7)
		#define PROCESSOR_ARM
	#endif
#endif

// PLATFORM_PTR_SIZE
// Platform pointer size; same as sizeof(void*).
// This is not the same as sizeof(int), as int is usually 32 bits on
// even 64 bit platforms.
//
// _WIN64 is defined by Win64 compilers, such as VC++.
// _M_IA64 is defined by VC++ and Intel compilers for IA64 processors.
// __LP64__ is defined by HP compilers for the LP64 standard.
// _LP64 is defined by the GCC and Sun compilers for the LP64 standard.
// __ia64__ is defined by the GCC compiler for IA64 processors.
// __arch64__ is defined by the Sparc compiler for 64 bit processors.
// __mips64__ is defined by the GCC compiler for MIPS processors.
// __powerpc64__ is defined by the GCC compiler for PowerPC processors.
// __64BIT__ is defined by the AIX compiler for 64 bit processors.
// __sizeof_ptr is defined by the ARM compiler (armcc, armcpp).
//
#ifndef PLATFORM_PTR_SIZE
	#if defined(__WORDSIZE) // Defined by some variations of GCC.
		#define PLATFORM_PTR_SIZE ((__WORDSIZE) / 8)
	#elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__aarch64__) || defined(__mips64__) || defined(__64BIT__) || defined(__Ptr_Is_64)
		#define PLATFORM_PTR_SIZE 8
	#elif defined(__CC_ARM) && (__sizeof_ptr == 8)
		#define PLATFORM_PTR_SIZE 8
	#else
		#define PLATFORM_PTR_SIZE 4
	#endif
#endif



// PLATFORM_WORD_SIZE
// This defines the size of a machine word. This will be the same as
// the size of registers on the machine but not necessarily the same
// as the size of pointers on the machine. A number of 64 bit platforms
// have 64 bit registers but 32 bit pointers.
//
#ifndef PLATFORM_WORD_SIZE
   #if (PLATFORM_PTR_SIZE == 8)
	  #define PLATFORM_WORD_SIZE 8
   #else
	  #define PLATFORM_WORD_SIZE PLATFORM_PTR_SIZE
   #endif
#endif

// PLATFORM_MIN_MALLOC_ALIGNMENT
// This defines the minimal alignment that the platform's malloc 
// implementation will return. This should be used when writing custom
// allocators to ensure that the alignment matches that of malloc
#ifndef PLATFORM_MIN_MALLOC_ALIGNMENT
	#if defined PLATFORM_APPLE
		#define PLATFORM_MIN_MALLOC_ALIGNMENT 16
	#else
		#define PLATFORM_MIN_MALLOC_ALIGNMENT (PLATFORM_PTR_SIZE * 2)
	#endif
#endif


// MISALIGNED_SUPPORT_LEVEL
// Specifies if the processor can read and write built-in types that aren't
// naturally aligned.
//    0 - not supported. Likely causes an exception.
//    1 - supported but slow.
//    2 - supported and fast.
//
#ifndef MISALIGNED_SUPPORT_LEVEL
	#if defined(PROCESSOR_X64) || defined(PROCESSOR_X86_64)
		#define MISALIGNED_SUPPORT_LEVEL 2
	#else
		#define MISALIGNED_SUPPORT_LEVEL 0
	#endif
#endif

// Macro to determine if a Windows API partition is enabled. Always false on non Microsoft platforms.
#if !defined(WINAPI_FAMILY_PARTITION)
	#define WINAPI_FAMILY_PARTITION(Partition) (0)
#endif


// CACHE_LINE_SIZE
// Specifies the cache line size broken down by compile target.
// This the expected best guess values for the targets that we can make at compilation time.

#ifndef CACHE_LINE_SIZE
	#if   defined(PROCESSOR_X86)      
		#define CACHE_LINE_SIZE 32    // This is the minimum possible value.
	#elif defined(PROCESSOR_X86_64)  
		#define CACHE_LINE_SIZE 64    // This is the minimum possible value
	#elif defined(PROCESSOR_ARM32)
		#define CACHE_LINE_SIZE 32    // This varies between implementations and is usually 32 or 64. 
	#elif defined(PROCESSOR_ARM64)
		#define CACHE_LINE_SIZE 64    // Cache line Cortex-A8  (64 bytes) http://shervinemami.info/armAssembly.html however this remains to be mostly an assumption at this stage
	#elif (PLATFORM_WORD_SIZE == 4)
		#define CACHE_LINE_SIZE 32    // This is the minimum possible value
	#else
		#define CACHE_LINE_SIZE 64    // This is the minimum possible value
	#endif
#endif


#endif // INCLUDED_eaplatform_H









